package com.srmt.document.feishu.internal;

import com.lark.oapi.Client;
import com.srmt.feishu.client.FeishuClient;
import com.lark.oapi.service.docx.v1.model.*;
import com.srmt.document.exception.ContentException;
import com.srmt.document.exception.DocumentOperationException;
import com.srmt.document.feishu.internal.core.BlockContext;
import com.srmt.document.feishu.internal.core.BlockUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 飞书TextElement级别定位工具类
 * 
 * 专注于在TextElement级别进行精确的文本定位，不包含任何写操作。
 * 所有写操作应该通过ContentWriter进行。
 * 
 * @author srmt
 * @since 3.0.0
 */
public class FeishuTextElementLocator {
    
    private static final Logger logger = LoggerFactory.getLogger(FeishuTextElementLocator.class);
    
    private final FeishuClient client;
    
    /**
     * TextElement定位信息
     */
    public static class TextElementLocation {
        private final String blockId;
        private final Block block;
        private final int elementIndex;
        private final TextElement element;
        private final Text textContainer;
        
        public TextElementLocation(String blockId, Block block, int elementIndex, 
                                  TextElement element, Text textContainer) {
            this.blockId = blockId;
            this.block = block;
            this.elementIndex = elementIndex;
            this.element = element;
            this.textContainer = textContainer;
        }
        
        public String getBlockId() { return blockId; }
        public Block getBlock() { return block; }
        public int getElementIndex() { return elementIndex; }
        public TextElement getElement() { return element; }
        public Text getTextContainer() { return textContainer; }
    }
    
    public FeishuTextElementLocator(FeishuClient client) {
        if (client == null) {
            throw new IllegalArgumentException("客户端不能为null");
        }
        this.client = client;
    }
    
    /**
     * 通过锚点文本查找TextElement位置
     * 
     * @param documentId 文档ID
     * @param anchorText 锚点文本
     * @return TextElement位置信息
     * @throws ContentException 如果找不到锚点
     */
    public TextElementLocation findTextElementByAnchor(String documentId, String anchorText) 
            throws ContentException {
        logger.debug("通过锚点文本查找文本元素: {} in document: {}", anchorText, documentId);
        
        try {
            // 创建上下文（唯一的API调用）
            BlockContext context = new BlockContext(client, documentId);
            
            // 遍历所有Block查找锚点
            for (Block block : context.getBlocks()) {
                Text textContainer = BlockUtils.getTextFromBlock(block);
                if (textContainer == null || textContainer.getElements() == null) {
                    continue;
                }
                
                TextElement[] elements = textContainer.getElements();
                for (int i = 0; i < elements.length; i++) {
                    TextElement element = elements[i];
                    String content = BlockUtils.extractTextFromTextElement(element);
                    if (content.contains(anchorText)) {
                        logger.debug("在块{}的元素索引{}处找到锚点", 
                                   block.getBlockId(), i);
                        return new TextElementLocation(block.getBlockId(), block, i, 
                                                      element, textContainer);
                    }
                }
            }
            
            throw new ContentException("Anchor text 未找到: " + anchorText);
            
        } catch (DocumentOperationException e) {
            throw new ContentException("通过锚点查找文本元素失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 查找所有包含指定文本的TextElement位置
     * 
     * @param documentId 文档ID
     * @param searchText 搜索文本
     * @return TextElement位置信息列表
     * @throws ContentException 如果操作失败
     */
    public List<TextElementLocation> findAllTextElements(String documentId, String searchText) 
            throws ContentException {
        logger.debug("查找所有包含文本的文本元素: {} in document: {}", searchText, documentId);
        
        List<TextElementLocation> locations = new ArrayList<>();
        
        try {
            // 创建上下文（唯一的API调用）
            BlockContext context = new BlockContext(client, documentId);
            
            // 遍历所有Block查找文本
            for (Block block : context.getBlocks()) {
                Text textContainer = BlockUtils.getTextFromBlock(block);
                if (textContainer == null || textContainer.getElements() == null) {
                    continue;
                }
                
                TextElement[] elements = textContainer.getElements();
                for (int i = 0; i < elements.length; i++) {
                    TextElement element = elements[i];
                    String content = BlockUtils.extractTextFromTextElement(element);
                    if (content.contains(searchText)) {
                        locations.add(new TextElementLocation(block.getBlockId(), block, i, 
                                                             element, textContainer));
                    }
                }
            }
            
            return locations;
            
        } catch (DocumentOperationException e) {
            throw new ContentException("查找全部文本元素失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 读取锚点后的文本（从同一个Block内的后续TextElements读取）
     * 
     * @param documentId 文档ID
     * @param anchorText 锚点文本
     * @param includeAnchor 是否包含锚点本身
     * @return 锚点后的文本
     * @throws ContentException 如果操作失败
     */
    public String readTextAfterAnchor(String documentId, String anchorText, boolean includeAnchor) 
            throws ContentException {
        logger.debug("读取锚点后的文本: {}", anchorText);
        
        try {
            // 查找锚点位置
            TextElementLocation location = findTextElementByAnchor(documentId, anchorText);
            
            StringBuilder result = new StringBuilder();
            TextElement[] elements = location.getTextContainer().getElements();
            
            // 从锚点元素开始读取
            int startIndex = includeAnchor ? location.getElementIndex() : location.getElementIndex() + 1;
            
            for (int i = startIndex; i < elements.length; i++) {
                String text = BlockUtils.extractTextFromTextElement(elements[i]);
                
                // 如果是锚点元素且不包含锚点，则跳过锚点文本部分
                if (i == location.getElementIndex() && !includeAnchor) {
                    int anchorIndex = text.indexOf(anchorText);
                    if (anchorIndex >= 0) {
                        text = text.substring(anchorIndex + anchorText.length());
                    }
                }
                
                result.append(text);
            }
            
            return result.toString();
            
        } catch (Exception e) {
            if (e instanceof ContentException) {
                throw (ContentException) e;
            }
            throw new ContentException("读取锚点后的文本失败: " + e.getMessage(), e);
        }
    }
}